import 'dart:convert';
import 'dart:core';

import 'package:common_utils/common_utils.dart';
import 'package:flutter/material.dart';

import '../storages/storage.dart';

class LogInfo {
  late final String title;
  late final String content;

  LogInfo({this.title = '', this.content = ''});

  //通过JSON构造
  LogInfo.fromJson(Map<String, dynamic> json) {
    title = json["t"] ?? '';
    content = json["errorText"] ?? '';
  }

  //转成JSON
  Map<String, dynamic> toJson() {
    Map<String, dynamic> json = {};
    json["t"] = title;
    json["errorText"] = content;
    return json;
  }
}

/// 系统日志
class SystemLog {
  // 单例
  static SystemLog? _instance;
  List<LogInfo> _errors;
  void Function(FlutterErrorDetails)? _onError;
  late bool _inited;

  factory SystemLog() {
    _instance ??= SystemLog._();
    return _instance!;
  }

  SystemLog._() : _errors = <LogInfo>[] {
    _errors = <LogInfo>[];
    _inited = false;

    _onError = FlutterError.onError; //先将 onerror 保存起来
    FlutterError.onError = (FlutterErrorDetails details) {
      try {
        err('${details.exceptionAsString()}\r\n${details.stack}');
      } catch (e) {}
    };
  }

  void init() {
    var json = Storage.getString('work_page_error');
    if (json != '') {
      _errors.addAll(
          (jsonDecode(json) as List<dynamic>).map((e) => LogInfo.fromJson(e)));
    }

    _inited = true;
  }

  String getDefTitle() {
    return DateUtil.formatDate(DateTime.now(),
        format: "yyyy-MM-dd HH:mm:ss.SSS");
  }

  static List<LogInfo> get errors {
    return _instance?._errors.reversed.toList() ?? [];
  }

  static void clear() {
    Storage.remove('work_page_error');
    _instance?._errors.clear();
  }

  static void err([dynamic content = '', String? title]) {
    title ??= _instance?.getDefTitle() ?? '';
    if (content is! String) {
      content = jsonDecode(content);
    }

    _instance?._errors.add(LogInfo(title: title, content: content));
    _instance?._save();
  }

  void _save() {
    if (_errors.length > 100) {
      _errors.removeAt(0);
    }
    List<Map<String, dynamic>> tmpError =
        _errors.map((e) => e.toJson()).toList();
    if (_inited) {
      Storage.setJson('work_page_error', tmpError);
    }
  }
}
